//
// $Id: EngineXB.java 8 2007-04-18 13:47:40Z z_hossain $
//
// xChess is a multiplatform graphical chess user interface
// Copyright (C) 2007  MD. Z. Hossain <z_hossain@users.sf.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
// 02110-1301, USA.
//
// For more information visit http://xchess.sourceforge.net
//

package net.sourceforge.xchess;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import model.Move;

import control.AbsEngineAgent;
import event.EngineEvent;
import event.MoveEvent;
import gui.IChessContext;

public class EngineXB extends AbsEngineAgent {
		
	Pattern patternMove = Pattern.compile("(my)?\\s*move\\s*(is)?\\s*[:>=\\-]?\\s*([a-h][1-8][a-h][1-8][nbrq]?)", Pattern.CASE_INSENSITIVE);
	Pattern patternIllegal = Pattern.compile("(Illegal move.+)|(Error.+)", Pattern.CASE_INSENSITIVE);
		
	public EngineXB(IChessContext context) {
		super(context);
	}
	
	@Override
	public void initiate() {
		super.initiate();
		writeLine("xboard");
	}	
	
	@Override
	public void newGame() {
		writeLine("new");
		setPondering(false);
	}
	
	@Override
	protected void parseCommand() throws IOException {
		final String line = readLine();
		if(line == null) return;
				
		Matcher matcher;
		matcher = patternMove.matcher(line);
		
		if(matcher.matches()) {
			Move move = Notation.toMove(matcher.group(3).substring(0, 4));
			updateContext(move);
			fireMovePrinted(new EngineEvent(this, matcher.group(3)));
			fireMovePerformed(new MoveEvent(this, move));
		}
		matcher = patternIllegal.matcher(line);
		if(matcher.matches()) fireIllegalPrinted(new EngineEvent(this));
	}

	@Override
	public void userMove(Move move) {
		writeLine(Notation.toString(move));
	}
	
	@Override
	public void setMoveTime(int move, long time) {
		writeLine("level " + move + " " + getTime(time) + " 0");
	}

	@Override
	public void setBlitzTime(long base, long increment) {
		writeLine("level " + 0 + " " + getTime(base) + " " + increment / 1000);
	}
	
	private String getTime(long time) {
		time /= 1000;
		return time / 60 + ":" + (time % 60) / 1000;
	}

	@Override
	public void setPondering(boolean on) {
		if(on) writeLine("hard");
		else writeLine("easy");
	}

	@Override
	public void quitEngine() {
		writeLine("quit");
	}
}
